#include "recovery/ErrnoStatus.h"

namespace recovery {

const char *  ErrnoStatus::getErrnoState(int _errno) const {
    //TODO: thread-safe????
    return std::strerror(_errno);
}
std::string ErrnoStatus::what() const {
    if(code() == Code::kOK){
        return " OK ";
    }
	//[code] + state + [errnoMsg]
    std::string out = Status::what();
    if(auto * errnoMsg = getErrnoState(_errno); errnoMsg != nullptr){
        return Status::what() + ": " + errnoMsg;
    }
    return Status::what() + ": unknown errno(" + std::to_string(_errno) + ")";
}
Status ErrnoStatus::toStatus(const std::string_view & msg) const{
	if(isOK()){
		return *this;
	}

	Status s = Status::Errno();

	int bufLen = 0;
	int slen = 0;
	if(state() != nullptr){
		bufLen += (slen =  std::strlen(state()));
	}
	int enLen = 0;
	auto * errnoMsg = getErrnoState(_errno);
	if(errnoMsg != nullptr){
		bufLen += (enLen = std::strlen(errnoMsg));
	}

	char * buf = new char[bufLen+1];
	if(state() != nullptr){
		memcpy(buf, state(), slen);
	}
	if(errnoMsg != nullptr){
		memcpy(buf + slen, errnoMsg, enLen);
	}
	buf[bufLen] = '\0';

	s.state(buf);
    return s;
}

}// end of namespace recovery
